import { LOG } from '../../../ConsoleLogCtrl';
import { IMessage, MessagePriority } from './MessageTypes';

/**
 * 消息队列
 * 负责消息的排队、优先级管理和有序处理
 */
export class MessageQueue {
    /** 高优先级消息队列 */
    private highPriorityQueue: IMessage[] = [];
    
    /** 普通优先级消息队列 */
    private normalPriorityQueue: IMessage[] = [];
    
    /** 低优先级消息队列 */
    private lowPriorityQueue: IMessage[] = [];
    
    /** 队列统计信息 */
    private statistics: {
        totalEnqueued: number;
        totalDequeued: number;
        maxQueueSize: number;
        currentQueueSize: number;
    } = {
        totalEnqueued: 0,
        totalDequeued: 0,
        maxQueueSize: 0,
        currentQueueSize: 0
    };
    
    /** 最大队列大小限制 */
    private maxQueueSize: number = 1000;
    
    /**
     * 将消息加入队列
     * @param message 消息对象
     */
    public enqueue<T = any>(message: IMessage<T>): boolean {
        // 检查队列大小限制
        if (this.size() >= this.maxQueueSize) {
            LOG.warn(`消息队列已满，丢弃消息: ${message.type}`);
            return false;
        }
        
        // 根据优先级加入对应队列
        switch (message.priority) {
            case MessagePriority.HIGH:
                this.highPriorityQueue.push(message);
                break;
            case MessagePriority.NORMAL:
                this.normalPriorityQueue.push(message);
                break;
            case MessagePriority.LOW:
                this.lowPriorityQueue.push(message);
                break;
            default:
                this.normalPriorityQueue.push(message);
                break;
        }
        
        // 更新统计信息
        this.statistics.totalEnqueued++;
        this.statistics.currentQueueSize = this.size();
        this.statistics.maxQueueSize = Math.max(this.statistics.maxQueueSize, this.statistics.currentQueueSize);
        
        return true;
    }
    
    /**
     * 从队列中取出消息（按优先级顺序）
     */
    public dequeue<T = any>(): IMessage<T> | null {
        let message: IMessage<T> | null = null;
        
        // 按优先级顺序取出消息：高 -> 普通 -> 低
        if (this.highPriorityQueue.length > 0) {
            message = this.highPriorityQueue.shift() as IMessage<T>;
        } else if (this.normalPriorityQueue.length > 0) {
            message = this.normalPriorityQueue.shift() as IMessage<T>;
        } else if (this.lowPriorityQueue.length > 0) {
            message = this.lowPriorityQueue.shift() as IMessage<T>;
        }
        
        if (message) {
            this.statistics.totalDequeued++;
            this.statistics.currentQueueSize = this.size();
        }
        
        return message;
    }
    
    /**
     * 查看队列头部消息（不移除）
     */
    public peek<T = any>(): IMessage<T> | null {
        if (this.highPriorityQueue.length > 0) {
            return this.highPriorityQueue[0] as IMessage<T>;
        } else if (this.normalPriorityQueue.length > 0) {
            return this.normalPriorityQueue[0] as IMessage<T>;
        } else if (this.lowPriorityQueue.length > 0) {
            return this.lowPriorityQueue[0] as IMessage<T>;
        }
        
        return null;
    }
    
    /**
     * 检查队列是否为空
     */
    public isEmpty(): boolean {
        return this.size() === 0;
    }
    
    /**
     * 获取队列总大小
     */
    public size(): number {
        return this.highPriorityQueue.length + 
               this.normalPriorityQueue.length + 
               this.lowPriorityQueue.length;
    }
    
    /**
     * 获取各优先级队列大小
     */
    public getSizeByPriority(): {
        high: number;
        normal: number;
        low: number;
        total: number;
    } {
        return {
            high: this.highPriorityQueue.length,
            normal: this.normalPriorityQueue.length,
            low: this.lowPriorityQueue.length,
            total: this.size()
        };
    }
    
    /**
     * 清空队列
     */
    public clear(): void {
        const totalCleared = this.size();
        
        this.highPriorityQueue.length = 0;
        this.normalPriorityQueue.length = 0;
        this.lowPriorityQueue.length = 0;
        
        this.statistics.currentQueueSize = 0;
        
        if (totalCleared > 0) {
            LOG.log(`清空消息队列，共清除${totalCleared}条消息`);
        }
    }
    
    /**
     * 清空指定优先级的队列
     * @param priority 消息优先级
     */
    public clearByPriority(priority: MessagePriority): void {
        let clearedCount = 0;
        
        switch (priority) {
            case MessagePriority.HIGH:
                clearedCount = this.highPriorityQueue.length;
                this.highPriorityQueue.length = 0;
                break;
            case MessagePriority.NORMAL:
                clearedCount = this.normalPriorityQueue.length;
                this.normalPriorityQueue.length = 0;
                break;
            case MessagePriority.LOW:
                clearedCount = this.lowPriorityQueue.length;
                this.lowPriorityQueue.length = 0;
                break;
        }
        
        this.statistics.currentQueueSize = this.size();
        
        if (clearedCount > 0) {
            LOG.log(`清空${priority}优先级队列，共清除${clearedCount}条消息`);
        }
    }
    
    /**
     * 移除指定类型的消息
     * @param messageType 消息类型
     */
    public removeByType(messageType: string): number {
        let removedCount = 0;
        
        // 从高优先级队列移除
        const highFiltered = this.highPriorityQueue.filter(msg => {
            if (msg.type === messageType) {
                removedCount++;
                return false;
            }
            return true;
        });
        this.highPriorityQueue = highFiltered;
        
        // 从普通优先级队列移除
        const normalFiltered = this.normalPriorityQueue.filter(msg => {
            if (msg.type === messageType) {
                removedCount++;
                return false;
            }
            return true;
        });
        this.normalPriorityQueue = normalFiltered;
        
        // 从低优先级队列移除
        const lowFiltered = this.lowPriorityQueue.filter(msg => {
            if (msg.type === messageType) {
                removedCount++;
                return false;
            }
            return true;
        });
        this.lowPriorityQueue = lowFiltered;
        
        this.statistics.currentQueueSize = this.size();
        
        if (removedCount > 0) {
            LOG.log(`移除消息类型${messageType}，共移除${removedCount}条消息`);
        }
        
        return removedCount;
    }
    
    /**
     * 获取队列中指定类型消息的数量
     * @param messageType 消息类型
     */
    public countByType(messageType: string): number {
        let count = 0;
        
        count += this.highPriorityQueue.filter(msg => msg.type === messageType).length;
        count += this.normalPriorityQueue.filter(msg => msg.type === messageType).length;
        count += this.lowPriorityQueue.filter(msg => msg.type === messageType).length;
        
        return count;
    }
    
    /**
     * 设置最大队列大小
     * @param maxSize 最大大小
     */
    public setMaxQueueSize(maxSize: number): void {
        this.maxQueueSize = Math.max(1, maxSize);
        
        // 如果当前队列超过新的限制，移除最旧的低优先级消息
        while (this.size() > this.maxQueueSize) {
            if (this.lowPriorityQueue.length > 0) {
                this.lowPriorityQueue.shift();
            } else if (this.normalPriorityQueue.length > 0) {
                this.normalPriorityQueue.shift();
            } else if (this.highPriorityQueue.length > 0) {
                this.highPriorityQueue.shift();
            }
        }
        
        this.statistics.currentQueueSize = this.size();
    }
    
    /**
     * 获取最大队列大小
     */
    public getMaxQueueSize(): number {
        return this.maxQueueSize;
    }
    
    /**
     * 获取队列统计信息
     */
    public getStatistics(): {
        totalEnqueued: number;
        totalDequeued: number;
        maxQueueSize: number;
        currentQueueSize: number;
        queueSizes: {
            high: number;
            normal: number;
            low: number;
        };
    } {
        return {
            ...this.statistics,
            queueSizes: {
                high: this.highPriorityQueue.length,
                normal: this.normalPriorityQueue.length,
                low: this.lowPriorityQueue.length
            }
        };
    }
    
    /**
     * 重置统计信息
     */
    public resetStatistics(): void {
        this.statistics = {
            totalEnqueued: 0,
            totalDequeued: 0,
            maxQueueSize: 0,
            currentQueueSize: this.size()
        };
    }
    
    /**
     * 调试信息：打印队列状态
     */
    public debugPrintQueue(): void {
        LOG.log('=== 消息队列状态 ===');
        LOG.log(`总大小: ${this.size()}`);
        LOG.log(`高优先级: ${this.highPriorityQueue.length}`);
        LOG.log(`普通优先级: ${this.normalPriorityQueue.length}`);
        LOG.log(`低优先级: ${this.lowPriorityQueue.length}`);
        LOG.log(`最大队列大小: ${this.maxQueueSize}`);
        LOG.log('统计信息:', this.statistics);
        LOG.log('==================');
    }
}